﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Mahanet.Abyss.PathCalculation
{
	public class Segment2D
	{
		#region C'tor

		public Segment2D(Line2D line)
			: this(line, 0, 1)
		{
		}

		public Segment2D(Line2D line, double startPosition, double endPosition)
		{
			this.Line = line;
			this.StartPosition = startPosition;
			this.EndPosition = endPosition;
		}

		public Segment2D(Coordinate2D startPoint, Coordinate2D endPoint)
		{
			Vector2D lineVector = new Vector2D(startPoint, endPoint);
			this.Line = new Line2D(startPoint, lineVector);
			this.StartPosition = 0;
			this.EndPosition = lineVector.Length();
		}

		#endregion

		#region Public Properties

		public Line2D Line { get; private set; }
		public double StartPosition { get; private set; }
		public double EndPosition { get; private set; }

		public Coordinate2D StartPoint
		{
			get
			{
				return this.Line.LinePoint + this.StartPosition * this.Line.NormalizedDirection;
			}
		}

		public Coordinate2D EndPoint
		{
			get
			{
				return this.Line.LinePoint + this.EndPosition * this.Line.NormalizedDirection;
			}
		}

		#endregion

		#region Public Methods

		public Coordinate2D GetPointOnParameter(double t)
		{
			return this.Line.LinePoint + t * this.Line.NormalizedDirection;
		}

		public bool IsPointOnSegment(Coordinate2D coordinate)
		{
			if(!this.Line.IsPointOnLine(coordinate))
				return false;
			
			Vector2D distanceVector = new Vector2D(this.Line.LinePoint, coordinate);
			double signedDistance = distanceVector.Dot(this.Line.NormalizedDirection);

			return signedDistance >= this.StartPosition && signedDistance <= this.EndPosition;
		}

		public double Length()
		{
			return this.EndPosition - this.StartPosition;
		}

		#endregion
	}
}
